package org.swim.session;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.jboss.ejb3.annotation.RemoteBinding;
import org.swim.entity.FriendRequests;
import org.swim.entity.User;


@Stateless
@RemoteBinding(jndiBinding="FriendshipManagerRemote")
public class FriendshipManager implements FriendshipManagerRemote {

	/**
	 * Manager degli entity beans. Permette di interagire direttamente col database inserendo e ricercando dati
	 */
	@PersistenceContext(unitName="swim") private EntityManager manager;
	
	@Override
	public int createNewFriendshipRequest(int senderID, int recipientID) {
		
		FriendRequests toDefine=new FriendRequests();
		
		User sender=manager.find(User.class, senderID);
		User recipient=manager.find(User.class, recipientID);
		
	
		long dataMilli = System.currentTimeMillis(); 
		Date data = new Date( dataMilli );
		
		toDefine.setMittente(sender);
		toDefine.setDestinatario(recipient);
		toDefine.setApprovata(false);
		toDefine.setDataInvio(data);
		
		manager.persist(toDefine);
		
		return toDefine.getIdRichiesta();
	}

	@Override
	public void approveFriendshipRequest(int requestID) {

		FriendRequests toApprove=new FriendRequests();
		
		toApprove=manager.find(FriendRequests.class, requestID);
		toApprove.setApprovata(true);
		
	}
	
	@Override
	public void denyFriendship(int requestID)
	{
		FriendRequests toDeny=new FriendRequests();
		
		toDeny=manager.find(FriendRequests.class, requestID);
		
		this.deleteFriendshipRequest(requestID);
		
	}

	@Override
	public void deleteFriendshipRequest(int requestID) {
		
		FriendRequests ram = new FriendRequests();
		ram = manager.find(FriendRequests.class, requestID);
		if(ram != null)
			manager.remove(ram);	
		
	}
	

	@Override
	public List<User> getAllUserFriend(int userID) {
		
		List<User> result = new ArrayList<User>();
		
		try 
		{
			User USER=manager.find(User.class, userID);

			
			Query q = manager.createQuery("SELECT OBJECT(ram) FROM FriendRequests AS ram" +
											" WHERE ram.approvata=true AND (ram.mittente=:U"+
											" OR ram.destinatario=:U )");
			q.setParameter("U", USER );
			
			
			@SuppressWarnings("unchecked")
			Collection<FriendRequests> coll = (Collection<FriendRequests>) q.getResultList();

			Iterator<FriendRequests> itar = coll.iterator();
			
			while (itar.hasNext())
			{	
				FriendRequests ram = itar.next();
				
				if(ram.getMittente().getId()==userID){
					result.add(ram.getDestinatario());
				}
				else
				{
					result.add(ram.getMittente());
				}
			}
			
		} 
		catch (EntityNotFoundException exc){} 
		
		return result;		
	}

	@Override
	public List<FriendRequests> getAllUserRecievedFrindshipRequest(int userID) {
		
		List<FriendRequests> result = new ArrayList<FriendRequests>();
		
		try 
		{
			User DESTINATARIO=manager.find(User.class, userID);
			
			Query q = manager.createQuery("SELECT OBJECT(ram) FROM FriendRequests AS ram" +
											" WHERE ram.approvata=false AND ram.destinatario=:U");
			q.setParameter("U", DESTINATARIO);
			
			
			@SuppressWarnings("unchecked")
			Collection<FriendRequests> coll = (Collection<FriendRequests>) q.getResultList();

			Iterator<FriendRequests> itar = coll.iterator();
			
			while (itar.hasNext())
			{	
				result.add(itar.next());
			}
			
		} 
		catch (EntityNotFoundException exc){} 
		
		return result;		
	}

	@Override
	public List<FriendRequests> getAllUserSentFriendshipRequest(int userID) {
		
		List<FriendRequests> result = new ArrayList<FriendRequests>();
		
		try 
		{
			User MITTENTE=manager.find(User.class, userID);
			
			Query q = manager.createQuery("SELECT OBJECT(fr) FROM FriendRequests AS fr" +
											" WHERE fr.approvata=false AND fr.mittente=:U");
			q.setParameter("U", MITTENTE);
			
			@SuppressWarnings("unchecked")
			Collection<FriendRequests> coll = (Collection<FriendRequests>) q.getResultList();

			Iterator<FriendRequests> itar = coll.iterator();
			
			while (itar.hasNext())
			{	
				result.add(itar.next());
			}
			
		} 
		catch (EntityNotFoundException exc){} 
		
		return result;		
	}

	@Override
	public boolean areFriend(int firstUserID, int secondUserID) {	
		Query q=manager.createQuery("SELECT OBJECT(fr) FROM FriendRequests AS fr" +
				" WHERE fr.approvata=true AND ((fr.mittente.id=:FIRST AND fr.destinatario.id=:SECOND)" +
				 " OR (fr.mittente.id=:SECOND AND fr.destinatario.id=:FIRST))");
				
		q.setParameter("FIRST", firstUserID);
		q.setParameter("SECOND", secondUserID);
		try {
		q.getSingleResult();
		}
		catch (NoResultException e) {
			return false;
		}
		return true;

	}
	
	@Override
	public boolean pendingFriendRequest(int firstUserID, int secondUserID) {
		
		User first=manager.find(User.class, firstUserID);
		User second=manager.find(User.class, secondUserID);

		
		Query q=manager.createQuery("SELECT OBJECT(fr) FROM FriendRequests AS fr" +
				" WHERE fr.approvata=false AND ((fr.mittente=:FIRST AND fr.destinatario=:SECOND)" +
				 " OR (fr.mittente=:SECOND AND fr.destinatario=:FIRST))");
		
		q.setParameter("FIRST", first);
		q.setParameter("SECOND", second);

		try {
		q.getSingleResult();
		}
		catch (NoResultException e) {
			return false;
		}
		return true;
	}


	@Override
	public int deleteFriendship(int firstUserID, int secondUserID) {
		
		
		if(this.areFriend(firstUserID, secondUserID))
		{
			Query q=manager.createQuery("SELECT OBJECT(fr) FROM FriendRequests AS fr" +
					" WHERE fr.approvata=true AND ((fr.mittente.id=:FIRST AND fr.destinatario.id=:SECOND)" +
					 " OR (fr.mittente.id=:SECOND AND fr.destinatario.id=:FIRST))");
					
			q.setParameter("FIRST", firstUserID);
			q.setParameter("SECOND", secondUserID);
			try {
			Object fr=q.getSingleResult();
			manager.remove((FriendRequests) fr);
			return 0;
			}
			catch (NoResultException e) {}
			
			
		}
		
		
		return -1;
		
	
		
	}
	
	
	
	
}
